#include "ASImageMgr.h"
#include "..\tool\ASLog.h"

#ifdef AS_USE_IMAGE_RESOURCE_MANAGER

static as_image_resmgr s_as_image_resmgr;

static ASINT as_image_resmgr_get_free_idx(as_image_resmgr* self)
{
    ASINT i = 0;

    if(!self)
        return -1;

    for(i = 0; i < AS_IMAGE_RES_MAX; i++)
    {
        if(self->infos[i].if_used == FALSE)
            return i;
    }

    return -1;
}

static ASINT as_image_resmgr_get_idx_by_path(as_image_resmgr* self, ASWSTR path)
{
    ASINT i = 0;

    if(!self || !path || as_wstrlen(path) <= 0)
        return -1;

    for(i = 0; i < AS_IMAGE_RES_MAX; i++)
    {
        if(self->infos[i].if_used == TRUE && as_wstrcmp(path, self->infos[i].path) == 0)
        {
            return i;
        }
    }

    return -1;
}

//static ASINT as_image_resmgr_get_idx_by_canvas_hdlr(as_image_resmgr* self, ASINT canvas_hdlr)
//{
//    ASINT i = 0;
//
//    if(!self || canvas_hdlr <= 0)
//        return -1;
//
//    for(i = 0; i < AS_IMAGE_RES_MAX; i++)
//    {
//        if(self->infos[i].if_used == TRUE && self->infos[i].canvas_hdlr == canvas_hdlr)
//        {
//            return i;
//        }
//    }
//
//    return -1;
//}

static ASINT as_image_resmgr_new_info(as_image_resmgr* self, ASINT idx, as_image_src_type type, ASWSTR path,
                                      ASINT if_resize, ASINT w, ASINT h)
{
    ASCHAR* ascii_path = NULL;
    ASINT ret = AS_OK, res_hdlr;

    if(!self || !path)
        return AS_INVALID_PARAM;

    as_wstrcpy(self->infos[idx].path, path);
    self->infos[idx].type = type;
    as_log_imgres("[AS]<imgres>---- as_image_resmgr_new_info: path[%s],type[%d]", as_ascii_from_ucs2(path), type);

    if(type == AS_IMAGE_FROM_RES)
    {
        ascii_path = as_calloc(as_wstrlen(self->infos[idx].path) + 1);

        if(!ascii_path)
        {
            as_log_fatal("[AS] <fatal error> calloc res path error!");
            ret = AS_MEMORY_NOT_ENOUGH;
            goto ERROR;
        }

        as_ucs2_to_ascii(ascii_path , self->infos[idx].path);
        res_hdlr = as_load_res_internal(ascii_path, &self->infos[idx].res_info);
        as_free(ascii_path);

        if(res_hdlr < 0)
        {
            as_log_fatal("[AS] <fatal error> load_res_internal error!");
            ret = AS_INTERNAL_ERROR;
            goto ERROR;
        }
    }
    else if(type == AS_IMAGE_FROM_FILE)
    {
        //ASUINT8* res_data;
        //ASINT data_size;
        //VMFILE fh = -1;
        //VMUINT len;
        //fh = vm_file_open(path, MODE_READ, TRUE);
        //if(fh < VM_FILE_OK)
        //{
        //    ret = AS_INVALID_PARAM;
        //    goto ERROR;
        //}
        //if(vm_file_getfilesize(fh, (VMUINT*)&data_size) != 0)
        //{
        //    vm_file_close(fh);
        //    ret = AS_INTERNAL_ERROR;
        //    goto ERROR;
        //}
        //res_data = as_calloc(data_size);
        //if(res_data == NULL)
        //{
        //    vm_file_close(fh);
        //    ret = AS_MEMORY_NOT_ENOUGH;
        //    goto ERROR;
        //}
        //vm_file_read(fh, res_data, data_size, &len);
        //if((VMUINT)data_size != len)
        //{
        //    vm_free(res_data);
        //    vm_file_close(fh);
        //    ret = AS_INTERNAL_ERROR;
        //    goto ERROR;
        //}
        //vm_file_close(fh);
        //if(if_resize)
        //{
        //    self->infos[idx].canvas_hdlr = vm_graphic_load_image_resized(res_data, data_size, w, h);
        //}
        //else
        //{
        //    self->infos[idx].canvas_hdlr = vm_graphic_load_image(res_data, data_size);
        //}
        //if(self->infos[idx].canvas_hdlr < VM_GDI_SUCCEED)
        //{
        //    vm_free(res_data);
        //    ret = AS_INTERNAL_ERROR;
        //    goto ERROR;
        //}
    }

    self->infos[idx].if_used = TRUE;
    self->infos[idx].type = type;
    return self->infos[idx].res_info.res_hdlr;
ERROR:
    as_memset(&self->infos[idx], 0, sizeof(as_image_res_info));
    return ret;
}

static ASINT as_image_resmgr_add_info(as_image_resmgr* self, as_image_src_type type, ASWSTR path, as_res_info* out_p)
{
    ASINT idx = 0;

    if(!self || !path || as_wstrlen(path) <= 0)
        return AS_INVALID_PARAM;

    idx = as_image_resmgr_get_idx_by_path(self, path);

    if(idx == -1)
    {
        ASINT free_idx = as_image_resmgr_get_free_idx(self);
        ASINT hd;

        if(free_idx < 0)
        {
            return AS_MEMORY_NOT_ENOUGH;
        }

        hd = as_image_resmgr_new_info(self, free_idx, type, path, FALSE, 0, 0);

        if(hd >= 0)
        {
            as_memcpy(out_p, &self->infos[free_idx].res_info, sizeof(as_res_info));
            self->infos[free_idx].ref_counts++;
            return self->infos[free_idx].res_info.res_hdlr;
        }
        else
        {
            as_log_fatal("[AS] <fatal error> add res info error[%s]", as_ascii_from_ucs2(path));
            return AS_MEMORY_NOT_ENOUGH;
        }
    }
    else
    {
        as_memcpy(out_p, &self->infos[idx].res_info, sizeof(as_res_info));
        self->infos[idx].ref_counts++;
        return self->infos[idx].res_info.res_hdlr;
    }
}

//static ASINT as_image_resmgr_add_existed_info(as_image_resmgr* self, ASWSTR path, ASINT canvas_hdlr, as_image_src_type type)
//{
//    ASINT idx = 0;
//
//    if(!self || !path)
//    {
//        return AS_INVALID_PARAM;
//    }
//
//    idx = as_image_resmgr_get_idx_by_canvas_hdlr(self, canvas_hdlr);
//
//    if(idx < 0)
//    {
//        idx = as_image_resmgr_get_idx_by_path(self, path);
//    }
//
//    if(idx < 0)
//    {
//        //new info
//        idx = as_image_resmgr_get_free_idx(self);
//
//        if(idx < 0)
//            return AS_MEMORY_NOT_ENOUGH;
//
//        self->infos[idx].if_used = TRUE;
//        self->infos[idx].canvas_hdlr = canvas_hdlr;
//        as_wstrcpy(self->infos[idx].path, path);
//        self->infos[idx].type = type;
//        self->infos[idx].ref_counts++;
//    }
//    else
//    {
//        self->infos[idx].ref_counts++;
//    }
//
//    return self->infos[idx].canvas_hdlr;
//}

//static ASINT as_image_resmgr_resize_info(as_image_resmgr* self, ASWSTR path, ASINT w, ASINT h)
//{
//    ASINT idx;
//
//    if(!self || !path)
//    {
//        return AS_INVALID_PARAM;
//    }
//
//    idx = self->get_idx_by_path(self, path);
//
//    if(idx < 0)
//        return AS_INVALID_PARAM;
//
//    if(self->infos[idx].canvas_hdlr)
//    {
//        vm_graphic_release_canvas(self->infos[idx].canvas_hdlr);
//        self->infos[idx].canvas_hdlr = NULL;
//    }
//
//    return as_image_resmgr_new_info(self, idx, self->infos[idx].type, path, TRUE, w, h);
//}

static as_ret as_image_resmgr_delete_info_by_path(as_image_resmgr* self, ASWSTR path)
{
    ASINT idx = 0;

    if(!self || !path)
        return AS_INVALID_PARAM;

    idx = as_image_resmgr_get_idx_by_path(self, path);

    if(idx < 0)
        return AS_INVALID_PARAM;

    if(self->infos[idx].ref_counts > 1)
    {
        self->infos[idx].ref_counts--;
    }
    else
    {
        as_unload_res_internal(&self->infos[idx].res_info);
        //self->infos[idx].ref_counts--;
        //vm_graphic_release_canvas(self->infos[idx].canvas_hdlr);
        as_memset(&self->infos[idx], 0, sizeof(as_image_res_info));
    }

    return AS_OK;
}

//static as_ret as_image_resmgr_delete_canvas_for_reload(as_image_resmgr* self, ASINT canvas_hdlr)
//{
//    ASINT idx = 0;
//
//    if(!self || canvas_hdlr <= 0)
//        return AS_INVALID_PARAM;
//
//    idx = as_image_resmgr_get_idx_by_canvas_hdlr(self, canvas_hdlr);
//
//    if(idx < 0)
//        return AS_INVALID_PARAM;
//
//    vm_graphic_release_canvas(self->infos[idx].canvas_hdlr);
//    self->infos[idx].canvas_hdlr = NULL;
//    return AS_OK;
//}

//static as_ret as_image_resmgr_delete_info_by_hdlr(as_image_resmgr* self, ASINT canvas_hdlr)
//{
//    ASINT idx = 0;
//
//    if(!self || canvas_hdlr <= 0)
//        return AS_INVALID_PARAM;
//
//    idx = as_image_resmgr_get_idx_by_canvas_hdlr(self, canvas_hdlr);
//
//    if(idx < 0)
//        return AS_INVALID_PARAM;
//
//    if(self->infos[idx].ref_counts > 1)
//    {
//        self->infos[idx].ref_counts--;
//    }
//    else
//    {
//        self->infos[idx].ref_counts--;
//        vm_graphic_release_canvas(self->infos[idx].canvas_hdlr);
//        as_memset(&self->infos[idx], 0, sizeof(as_image_res_info));
//    }
//
//    return AS_OK;
//}

void as_image_resmgr_release_instance(as_image_resmgr* self);
static void as_image_resmgr_init(as_image_resmgr* self)
{
    if(!self)
        return;

    self->add = as_image_resmgr_add_info;
    //self->add_existed = as_image_resmgr_add_existed_info;
    //self->resize = as_image_resmgr_resize_info;
    self->delete_by_path = as_image_resmgr_delete_info_by_path;
    //self->delete_by_hdlr = as_image_resmgr_delete_info_by_hdlr;
    //self->delete_canvas_for_reload = as_image_resmgr_delete_canvas_for_reload;
    self->get_idx_by_path = as_image_resmgr_get_idx_by_path;
    self->release = as_image_resmgr_release_instance;
}

as_image_resmgr* as_image_resmgr_get_instance(void)
{
    as_image_resmgr* image_resmgr_p = &s_as_image_resmgr;
    //as_log("~~~~as_image_resmgr_get_instance");

    if(image_resmgr_p->if_inited == FALSE)
    {
        image_resmgr_p->if_inited = TRUE;
        as_image_resmgr_init(image_resmgr_p);
    }

    return image_resmgr_p;
}

void as_image_resmgr_release_instance(as_image_resmgr* self)
{
    ASINT i = 0;

    if(!self)
        return;

    for(i = 0; i < AS_IMAGE_RES_MAX; i++)
    {
        if(self->infos[i].if_used == TRUE)
        {
            as_unload_res_internal(&self->infos[i].res_info);
            as_memset(&self->infos[i], 0, sizeof(as_image_res_info));
        }
    }
}

#endif//AS_USE_IMAGE_RESOURCE_MANAGER